package org.smr.ministore.security.component.config;

import org.smr.ministore.security.component.config.success.LoginSuccessHandler;
import org.smr.ministore.security.component.session.MyExpiredSessionStrategy;
import org.smr.ministore.security.component.session.MyInvalidSessionStrategy;
import org.smr.ministore.security.core.AuthorizeConfigManager;
import org.smr.ministore.security.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

@Configuration
@EnableConfigurationProperties({SecurityProperties.class})
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    @Autowired
    private AuthenticationProvider usernameAndPasswordAuthenticationProvider;

    @Autowired
    private InvalidSessionStrategy invalidSessionStrategy;

    @Autowired
    private SessionInformationExpiredStrategy sessionInformationExpiredStrategy;


    @Autowired
    private AuthorizeConfigManager authorizeConfigManager;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

       /* http
                .formLogin()          // 定义当需要用户登录时候，转到的登录页面。
                .and()
                .authorizeRequests()    // 定义哪些URL需要被保护、哪些不需要被保护
                .anyRequest()        // 任何请求,登录后可以访问
                .authenticated();*/

        http.formLogin()          // 定义当需要用户登录时候，转到的登录页面。
                .loginPage(securityProperties.getLoginPage())      // 设置登录页面
                .loginProcessingUrl( securityProperties.getLoginProcessingUrl()) // 自定义的登录接口
                .permitAll()
                .successHandler(loginSuccessHandler)
                .and()
                .authorizeRequests()    // 定义哪些URL需要被保护、哪些不需要被保护
                    .antMatchers("/login.html").permitAll()   // 设置所有人都可以访问登录页面
                    .anyRequest()        // 任何请求,登录后可以访问
                    .authenticated()
                .and()
               /* .sessionManagement()
                    .invalidSessionStrategy(invalidSessionStrategy) // session超时跳转
                    .maximumSessions( securityProperties.getMaximumSessions()) // 最大并发session
                    .maxSessionsPreventsLogin( securityProperties.getSession().isMaxSessionsPreventsLogin())    // 是否阻止新的登录
                    .expiredSessionStrategy( sessionInformationExpiredStrategy )      // 并发session失效原因
                .and().and()*/
                .csrf().disable();     // 关闭csrf防护

        authorizeConfigManager.config(http.authorizeRequests());

    }

    @Override
    protected void configure( AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider( usernameAndPasswordAuthenticationProvider );
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    @ConditionalOnMissingBean(InvalidSessionStrategy.class)
    public InvalidSessionStrategy invalidSessionStrategy(){
        return new MyInvalidSessionStrategy(securityProperties.getSessionInvalidUrl());
    }

    @Bean
    @ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
    public SessionInformationExpiredStrategy sessionInformationExpiredStrategy(){
        return new MyExpiredSessionStrategy(securityProperties.getSessionInvalidUrl());
    }


}
